home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 176-200 / scopedisk185 / dfc5 / dfc5.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  11KB  |  396 lines

  1. #include "DFC5.h"
  2.  
  3. #define ESC 0x1B
  4. #define RETURN 0x0D
  5.  
  6. /*
  7.  * Mask for EnableGadgets
  8.  */
  9.  
  10. #define ALLMASK 0x1FFFF
  11. #define COPYMASK 0x03D00
  12. #define AGAINMASK 0x03D00
  13. #define FORMATMASK 0x03700
  14.  
  15. #define ALLMSGS 0x3F
  16.  
  17. static char Key2Gadget[39] = { DF0S, DF1S, DF2S, DF3S, DF0D, DF1D, DF2D, DF3D, -1, -1, -1, -1, -1, -1, -1, -1, -1, AUTO, BUFFER, -1, DATE, -1, FORMAT, GO, -1, -1, -1, -1, -1, -1, FFS, -1, -1, -1, REPEAT, STOP, TALK, -1, VERIFY };
  18. static char NoBufferMsg[] = "Sorry, I need a buffer.";
  19. static char NoDiskMsg[] = "Can't open disk.";
  20. static char NoDestMsg[] = "Sorry, I need a destination.";
  21. static char NoSourceMsg[] = "Sorry, I need a source.";
  22. static char NoDiskPresentMsg[] = "No disk in unit x.";
  23. static char WriteProtectedMsg[] = "Disk in unit x is write protected.";
  24. static char GfxName[] = "graphics.library";
  25.  
  26. extern struct MsgPort *MainPort;
  27.  
  28. static struct Window *Window;
  29. static char *FormatBuffer, MsgLocked[6],
  30.                 Source = -1, Dest, ActualSource, ActualDest,
  31.                 Verify=1, Buffer, BufferUsed, BufferTrack,
  32.                 Date=1, UseFFS, Fuga, Copying, Formatting,
  33.                 Passes = 1, CurrentPass, CurrentStartTrack,
  34.                 CurrentEndTrack, Track, TracksPerPass = 80;
  35.  
  36. /*
  37.  * This routine sends an internal message with given parameters and locks it.
  38.  */
  39.  
  40. void SendAndLockMsg(int Unit, int Action, int n) {
  41.  
  42.     SendMsg(Unit, Action, n);
  43.     MsgLocked[Unit] = 1;
  44. }
  45.  
  46. /*
  47.  * The same, but the message is simply re-sent (for retrying errors).
  48.  */
  49.  
  50. void ReSendAndLockMsg(struct IMsg *Message) {
  51.  
  52.     SendAndLockMsg(Message->im_ID, Message->im_Action, Message->im_n);
  53. }
  54.  
  55. /*
  56.  * Check if units in the Mask have locked msgs.
  57.  */
  58.  
  59. int NoLockedMsgs(int Mask) {
  60.  
  61.     register int i;
  62.  
  63.     for(i=0; i<6; i++) if (MsgLocked[i] && (DEST(i) & Mask)) return(FALSE);
  64.     return(TRUE);
  65. }
  66.  
  67. /*
  68.  * Here we stop any operation. If we weren't copying, and the buffer is on,
  69.  * we wipe the progress bar and reset the pass counter.
  70.  */
  71.  
  72. void Stop(void) {
  73.     if (Copying) {
  74.         if (Copying == 'G' && Buffer)
  75.             if (--CurrentPass<0) CurrentPass = Passes-1;
  76.         Copying = 0;
  77.         Track = CurrentEndTrack-1;
  78.         Beep(2400);
  79.     }
  80.     else {
  81.         CurrentPass = Passes-1;
  82.         if (Buffer) WipeProgress(Window, 0);
  83.     }
  84. }
  85.  
  86. /*
  87.  * Here we check if some fatal error was encountered.
  88.  */
  89.  
  90. int FatalErrors(struct IMsg *Message) {
  91.     if (Message->im_RC == NO_DISK) {
  92.         NoDiskPresentMsg[16] = 48+Message->im_ID;
  93.         Acknowledge(NoDiskPresentMsg);
  94.         return(1);
  95.     }
  96.     if (Message->im_RC == WRITE_PROTECTED) {
  97.         WriteProtectedMsg[13] = 48+Message->im_ID;
  98.         Acknowledge(WriteProtectedMsg);
  99.         return(1);
  100.     }
  101.     return(0);
  102. }
  103.  
  104.  
  105. /*
  106.  * The big thing!
  107.  * Apart from the open-all-stuff/close-all-stuff parts, this is simply a
  108.  * preposterously huge event loop.
  109.  */
  110.  
  111. void _main(void) {
  112.  
  113.     register int i;
  114.     register char *b;
  115.     register struct Gadget *G;
  116.  
  117.     struct IMsg *Message;
  118.     struct IntuiMessage *Msg;
  119.  
  120.     int Op, Class, Code;
  121.  
  122.     if ((GfxBase = (void *)OpenLibrary(GfxName,36))==NULL) {
  123.         if ((GfxBase = (void *)OpenLibrary(GfxName,33))==NULL) goto GameOver;
  124.         ReverseBorderColors();
  125.     }
  126.  
  127.     if (!SetUpPorts() ||
  128.         (IntuitionBase = (void *)OpenLibrary("intuition.library",33))==NULL ||
  129.         (Window = SetUpWindow())==NULL)
  130.         goto GameOver;
  131.  
  132.     SetUpAudio();
  133.  
  134.     FOREVER {
  135.  
  136.         do {
  137.  
  138.             Msg = (void *)GetMsg(Window->UserPort);
  139.             Message = (void *)GetMsg(MainPort);
  140.  
  141.             if (Msg) {
  142.  
  143.                 Code = Msg->Code ;
  144.                 Class = Msg->Class;
  145.                 G = (struct Gadget *)(Msg->IAddress);
  146.                 ReplyMsg((void *)Msg) ;
  147.  
  148.                 switch(Class) {
  149.                     case CLOSEWINDOW: Fuga = 1;
  150.                                             break;
  151.  
  152.                     case GADGETUP:
  153.                     case GADGETDOWN:
  154.                     case VANILLAKEY:
  155.                         if (Class == VANILLAKEY) {
  156.                             Op = toupper(Code);
  157.                             if (Op>='0' && Op<='V' && Key2Gadget[Op]>=0) G = GAddr(Key2Gadget[Op-48]);
  158.                             else G = NULL;
  159.                         }
  160.                         else Op = G->GadgetID;
  161.  
  162.                         switch(Op) {
  163.                             case RETURN:
  164.                                             Op = Buffer ? 'R' : 'G';
  165.                             case 'F':
  166.                             case 'R':
  167.                             case 'G':    if (Copying || !NoLockedMsgs(ALLMSGS) || (Op == 'F' && !(FormatBuffer = AllocMem(TRACKSIZE, MEMF_PUBLIC)))) break;
  168.                                             if (Op == 'G' && Source<0) {
  169.                                                 Acknowledge(NoSourceMsg);
  170.                                                 break;
  171.                                             }
  172.                                             if (((Op == 'G' && INDEST(Source)) || Op == 'R') && !Buffer) {
  173.                                                 Acknowledge(NoBufferMsg);
  174.                                                 break;
  175.                                             }
  176.                                             if ((Op == 'R' || Op == 'F' || (Op == 'G' && !Buffer)) && !Dest) {
  177.                                                 Acknowledge(NoDestMsg);
  178.                                                 break;
  179.                                             }
  180.                                             ActualDest = Dest;
  181.                                             switch(Copying = Op) {
  182.                                                 case 'G':
  183.                                                     EnableGadgets(Window, COPYMASK);
  184.                                                     ActualSource = Source;
  185.                                                     if (Buffer) ActualDest = DEST(4);
  186.                                                     if (++CurrentPass == Passes) CurrentPass = 0;
  187.                                                     break;
  188.                                                 case 'R':
  189.                                                     EnableGadgets(Window, AGAINMASK);
  190.                                                     ActualSource = 4;
  191.                                                     break;
  192.                                                 case 'F':
  193.                                                     EnableGadgets(Window, FORMATMASK);
  194.                                                     ActualSource = 5;
  195.                                                     break;
  196.                                             }
  197.  
  198.                                             if (Formatting = (Copying == 'F')) {
  199.                                                 CurrentStartTrack = 79;
  200.                                                 CurrentEndTrack = 0;
  201.                                             }
  202.                                             else {
  203.                                                 CurrentStartTrack = 79-CurrentPass*TracksPerPass;
  204.                                                 CurrentEndTrack = max(0, CurrentStartTrack-TracksPerPass+1);
  205.                                             }
  206.                                             Track = CurrentStartTrack;
  207.                                             WipeProgress(Window, 79-CurrentStartTrack);
  208.                                             for(i=0; i<5; i++) if (INACTUALDEST(i) || i == ActualSource) SendAndLockMsg(i, INIT, i == ActualSource && Date && !Formatting && CurrentPass == 0 ? -1 : CurrentStartTrack);
  209.                                             BufferUsed = DEST(ActualSource);
  210.                                             break;
  211.  
  212.                             case 'S':    Stop();
  213.                                             break;
  214.  
  215.                             case ESC:
  216.                             case 'Q':    Fuga = 1;
  217.                                             break;
  218.  
  219.  
  220.                             case 'B':
  221.                             case 'V':
  222.                             case 'D':
  223.                             case 'A':
  224.                             case 'N':
  225.                             case 'T':    if (!G) break;
  226.                                             if (Class == VANILLAKEY) ToggleGadget(Window, G);
  227.                                             i =  ((G->Flags & SELECTED) != 0);
  228.  
  229.                                             switch(Op) {
  230.                                                 case 'V':    Verify = i;
  231.                                                                 break;
  232.                                                 case 'D':    Date = i;
  233.                                                                 break;
  234.                                                 case 'A':    break;
  235.                                                 case 'N':    UseFFS = i;
  236.                                                                 break;
  237.                                                 case 'T':    if (i) {
  238.                                                                     if (!OpenVoice()) SelectGadget(Window, G, FALSE);
  239.                                                                 }
  240.                                                                 else CloseVoice();
  241.                                                                 break;
  242.                                                 case 'B':    if (i) {
  243.                                                                     if (Passes = OpenDiskTask(4)) {
  244.                                                                         Buffer = 1;
  245.                                                                     }
  246.                                                                     else {
  247.                                                                         SelectGadget(Window, G, FALSE);
  248.                                                                         Acknowledge("Not enough memory.");
  249.                                                                     }
  250.                                                                 }
  251.                                                                 else {
  252.                                                                     CloseDiskTask(4);
  253.                                                                     Buffer = 0;
  254.                                                                 }
  255.                                                                 if (!Buffer) {
  256.                                                                     Passes = 1;
  257.                                                                 }
  258.                                                                 TracksPerPass = 80/Passes+(Passes==3);
  259.                                                                 CurrentPass = Passes-1;
  260.                                                                 break;
  261.                                             }
  262.                                             break;
  263.                             case '0':
  264.                             case '1':
  265.                             case '2':
  266.                             case '3':    Op -= '0';
  267.                                             if (!G) break;
  268.                                             if (Class == VANILLAKEY) ToggleGadget(Window, G);
  269.  
  270.                                             if ((i = (G->Flags & SELECTED)) && OpenDiskTask(Op)) {
  271.                                                 if (Source == Op) break;
  272.                                                 if (Source>=0) {
  273.                                                     SelectGadget(Window, GAddr(DF0S)+Source, FALSE);
  274.                                                     if (!INDEST(Source)) CloseDiskTask(Source);
  275.                                                 }
  276.                                                 Source = Op;
  277.                                             }
  278.                                             else {
  279.                                                 SelectGadget(Window, G, FALSE);
  280.                                                 if (i) Acknowledge(NoDiskMsg);
  281.                                                 if (!INDEST(Op)) CloseDiskTask(Op);
  282.                                                 if (Op == Source) Source = -1;
  283.                                             }
  284.  
  285.                                             break;
  286.  
  287.                             case '4':
  288.                             case '5':
  289.                             case '6':
  290.                             case '7':    Op -= '4';
  291.                                             if (!G) break;
  292.                                             if (Class == VANILLAKEY) ToggleGadget(Window, G);
  293.  
  294.                                             if ((i = (G->Flags & SELECTED)) && OpenDiskTask(Op)) Dest |= DEST(Op);
  295.                                             else {
  296.                                                 Dest &= ~DEST(Op);
  297.                                                 SelectGadget(Window, G, FALSE);
  298.                                                 if (i) Acknowledge(NoDiskMsg);
  299.                                                 if (Op != Source) CloseDiskTask(Op);
  300.                                             }
  301.                                             break;
  302.                         }
  303.                         break;
  304.                 }
  305.             }
  306.  
  307.             if (Message) {
  308.  
  309.                 MsgLocked[Message->im_ID] = 0;
  310.  
  311.                 switch(Message->im_Action) {
  312.                     case INIT:    if (Message->im_ID == ActualSource && Message->im_RC == NOT_DOS) Acknowledge("This is not a DOS disk.");
  313.                                     break;
  314.  
  315.                     case READ_TRACK:
  316.                             if (Copying && Message->im_RC == READ_ERROR && ProblemsWithUnit("Read", Message->im_ID, Message->im_n)) {
  317.                                 ReSendAndLockMsg(Message);
  318.                                 break;
  319.                             }
  320.                             if (FatalErrors(Message)) Stop();
  321.  
  322.                             b = Message->im_p;
  323.                             BufferTrack = Message->im_n;
  324.                             BufferUsed = ActualDest;
  325.                             if (Formatting && Message->im_n>=0) MakeFormatData(Message->im_n, b = FormatBuffer, UseFFS);
  326.                             break;
  327.  
  328.                     case WRITE_TRACK:
  329.                     case WRITE_AND_VERIFY_TRACK:
  330.                             if (Copying &&
  331.                                 ((Message->im_RC == WRITE_ERROR && ProblemsWithUnit("Write", Message->im_ID, Message->im_n)) ||
  332.                                 (Message->im_RC == VERIFY_ERROR && ProblemsWithUnit("Verify", Message->im_ID, Message->im_n)))) {
  333.                                 ReSendAndLockMsg(Message);
  334.                                 break;
  335.                             }
  336.                             if (FatalErrors(Message)) Stop();
  337.  
  338.                             break;
  339.  
  340.                     case STOP_MOTOR:    if (Message->im_ID == ActualSource) {
  341.                                                 BufferUsed = ActualDest;
  342.                                                 BufferTrack = CurrentEndTrack-1;
  343.                                             }
  344.                                             else if (NoLockedMsgs(ActualDest)) {
  345.                                                 EnableGadgets(Window, ALLMASK);
  346.                                                 UpdateProgress(Window);
  347.                                                 if (FormatBuffer) {
  348.                                                     FreeMem(FormatBuffer, TRACKSIZE);
  349.                                                     FormatBuffer = NULL;
  350.                                                 }
  351.                                                 Copying = 0;
  352.                                             }
  353.                                             break;
  354.                 }
  355.  
  356.  
  357.                 if (NoLockedMsgs(ActualDest))
  358.                     for(i=0; i<5; i++)
  359.                         if (DEST(i) & BufferUsed & ActualDest) {
  360.                             BufferUsed &= ~DEST(i);
  361.                             if ((Date || Formatting) && BufferTrack==40) UpdateRootBlock(b);
  362.                             CopyBuffer(b, i, BufferTrack % TracksPerPass);
  363.                             SendAndLockMsg(i, (Copying && BufferTrack>=CurrentEndTrack) ? (Verify ? WRITE_AND_VERIFY_TRACK : WRITE_TRACK) : STOP_MOTOR, BufferTrack);
  364.                         }
  365.  
  366.                 if (!BufferUsed) {
  367.                     if (Copying && BufferTrack>=CurrentEndTrack) DrawProgress(Window, 79-BufferTrack, Buffer && Copying == 'G' ? 1 : 3);
  368.                     BufferUsed = DEST(ActualSource);
  369.                     if (BufferTrack == CurrentEndTrack+4) Beep(3000);
  370.                     if (Copying && BufferTrack == CurrentEndTrack-1) {
  371.                         Beep(4000);
  372.                         if (!Buffer || Formatting) Say("Operation completed.");
  373.                         else Say("Pass completed.");
  374.                     }
  375.                 }
  376.  
  377.                 if (!MsgLocked[ActualSource] && (BufferUsed & DEST(ActualSource)) && Track >= CurrentEndTrack-1) {
  378.                     SendAndLockMsg(ActualSource, (Copying && Track>=CurrentEndTrack) ? READ_TRACK : STOP_MOTOR, Track--);
  379.                 }
  380.             }
  381.         } while(Msg || Message);
  382.  
  383.         if (Fuga && NoLockedMsgs(ALLMSGS)) break;
  384.         Wait(1 << Window->UserPort->mp_SigBit | 1 << MainPort->mp_SigBit);
  385.     }
  386.  
  387. GameOver:
  388.     if (Window) CloseWindow(Window);
  389.     if (IntuitionBase) CloseLibrary((void *)IntuitionBase);
  390.     if (GfxBase) CloseLibrary((void *)GfxBase);
  391.     for(i=0; i<5; i++) CloseDiskTask(i);
  392.     CloseAudio();
  393.     CloseVoice();
  394.     ClosePorts();
  395. }
  396.